#include "Vector3D.h"
#include "Direction3D.h"
#include "Point3D.h"
#include <math.h>



Vector3D::Vector3D(){x=0.0;y=0.0;z=0.0;}
Vector3D::Vector3D(double x,double y,double z){set(x,y,z);}
Vector3D::Vector3D(Point3D &a,Point3D &b){set(a, b);}
Vector3D::~Vector3D(){}
Vector3D& Vector3D::set(double x,double y,double z){
	this->x=x;
	this->y=y;
	this->z=z;
	return *this;
}
Vector3D& Vector3D::set(Point3D &a, Point3D &b){
	//a-b
	this->x=a.getX()-b.getX();
	this->y=a.getY()-b.getY();
	this->z=a.getZ()-b.getZ();
	return *this;
}
Vector3D& Vector3D::set(Vector3D &a){
	x=a.getX();
	y=a.getY();
	z=a.getZ();
	return *this;
}
Vector3D& Vector3D::setX(double x){this->x=x;return *this;}
Vector3D& Vector3D::setY(double x){this->y=y;return *this;}
Vector3D& Vector3D::setZ(double x){this->z=z;return *this;}
double Vector3D::getX(){return x;}
double Vector3D::getY(){return y;}
double Vector3D::getZ(){return z;}
bool Vector3D::eq(Vector3D &a){return (x==a.getX()&&y==a.getY()&&x==a.getZ())?true:false;}
bool Vector3D::neq(Vector3D &a){return !neq(a);}
double Vector3D::magnitude(){return sqrt((x*x)+(y*y)+(z*z));}
Vector3D& Vector3D::direction(Direction3D &dir){
	dir.setFromLength(x, y, z);
	return *this;
}

//math
Vector3D& Vector3D::add(Vector3D &a){
	x+=a.getX();
	y+=a.getY();
	z+=a.getZ();
	return *this;
}
Vector3D& Vector3D::add(Vector3D &a, Vector3D &b){
	set(a);
	return add(b);
}
Vector3D& Vector3D::sub(Vector3D &a){
	x-=a.getX();
	y-=a.getY();
	z-=a.getZ();
	return *this;
}
Vector3D& Vector3D::sub(Vector3D &a, Vector3D &b){
	set(a);
	return sub(b);
}
Vector3D& Vector3D::multiply(double a){
	x*=a;
	y*=a;
	z*=a;
	return *this;
}
Vector3D& Vector3D::divide(double a){
	x/=a;
	y/=a;
	z/=a;
	return *this;
}
Vector3D& Vector3D::dot(Vector3D &a){
	x*=a.getX();
	y*=a.getY();
	z*=a.getZ();
	return *this;
}
Vector3D& Vector3D::dot(Vector3D &a, Vector3D &b){
	set(a);
	return dot(a);
}
Vector3D& Vector3D::cross(Vector3D &a){
	double newX,newY,newZ;
	newX = (y * a.getZ()) - (z * a.getY());
	newY = (z * a.getX()) - (x * a.getZ());
	newZ = (x * a.getY()) - (y * a.getX());
	x=newX;y=newY;z=newZ;
	return *this;
}
Vector3D& Vector3D::cross(Vector3D &a, Vector3D &b){
	set(a);
	return cross(b);
}

//operator overloads
Vector3D& Vector3D::operator+=(Vector3D &a){return add(a);}
Vector3D& Vector3D::operator-=(Vector3D &a){return sub(a);}
Vector3D& Vector3D::operator*=(Vector3D &dotV){return dot(dotV);}
Vector3D& Vector3D::operator*=(double magnitude){return multiply(magnitude);}
Vector3D& Vector3D::operator/=(Vector3D &crossV){return cross(crossV);}
Vector3D& Vector3D::operator/=(double magnitude){return divide(magnitude);}
bool Vector3D::operator==(Vector3D &a){return eq(a);}
bool Vector3D::operator!=(Vector3D &a){return neq(a);}
